package com.yfqy.app.modules.promotion.serviceimpl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yfqy.app.constant.GeneralConstants;
import com.yfqy.app.domain.entity.ProductSku;
import com.yfqy.app.domain.entity.ProductSpu;
import com.yfqy.app.domain.entity.ProductSpuImages;
import com.yfqy.app.domain.mapper.ProductSkuMapper;
import com.yfqy.app.domain.mapper.ProductSpuImagesMapper;
import com.yfqy.app.domain.mapper.ProductSpuMapper;
import com.yfqy.app.domain.mapper.PromotionMapper;
import com.yfqy.app.domain.mapper.PromotionProductMapper;
import com.yfqy.app.domain.mapper.PromotionRuleMapper;
import com.yfqy.app.enums.ErrorCode;
import com.yfqy.app.enums.ProductStatus;
import com.yfqy.app.exception.BusinessException;
import com.yfqy.app.modules.promotion.dto.PromotionQueryDTO;
import com.yfqy.app.modules.promotion.service.PromotionService;
import com.yfqy.app.modules.promotion.vo.PromotionProductVO;
import com.yfqy.app.modules.promotion.vo.PromotionRuleVO;
import com.yfqy.app.modules.promotion.vo.PromotionVO;
import com.yfqy.app.util.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class PromotionServiceImpl implements PromotionService {

    @Autowired
    private ProductSpuMapper productSpuMapper;
    @Autowired
    private ProductSkuMapper productSkuMapper;
    @Autowired
    private ProductSpuImagesMapper productSpuImagesMapper;
    @Autowired
    private PromotionMapper promotionMapper;
    @Autowired
    private PromotionProductMapper promotionProductMapper;
    @Autowired
    private PromotionRuleMapper promotionRuleMapper;


    @Override
    public PageInfo<PromotionVO> queryPromotionPage(PromotionQueryDTO queryDTO) {
        try {
            // 1. 分页查询促销活动基本信息
            PageHelper.startPage(queryDTO.getPageIndex(), queryDTO.getPageSize());
            List<PromotionVO> promotionVOS = promotionMapper.queryPromotionPage(queryDTO);
            if (CollUtil.isEmpty(promotionVOS)) {
                return new PageInfo<>(Collections.emptyList());
            }

            // 2. 准备基础数据
            List<Long> promotionIds = promotionVOS.stream().map(PromotionVO::getId).toList();

            // 3. 查询并处理促销商品信息
            Map<Long, PromotionProductVO> minPriceProductMap = processPromotionProducts(promotionVOS, promotionIds);

            // 4. 查询促销规则
            Map<Long, List<PromotionRuleVO>> ruleGroupPromotion = processPromotionRules(promotionIds);

            // 5. 查询商品信息并填充
            fillProductInfo(promotionVOS, minPriceProductMap, ruleGroupPromotion);

            return new PageInfo<>(promotionVOS);
        } catch (Exception e) {
            if (e instanceof BusinessException) {
                throw e;
            }
            throw new BusinessException(ErrorCode.SYSTEM_ERROR);
        } finally {
            PageHelper.clearPage();
        }

    }

    // 处理促销商品信息
    private Map<Long, PromotionProductVO> processPromotionProducts(List<PromotionVO> promotionVOS, List<Long> promotionIds) {
        // 根据促销活动Ids查询促销活动商品
        List<PromotionProductVO> promotionProductVOS = promotionProductMapper.selectPromotionProductsByPromotionIds(promotionIds);
        // 收集SPU/SKU ID
        Set<Long> spuIds = new HashSet<>();
        Set<Long> skuIds = new HashSet<>();
        Map<Long, List<PromotionProductVO>> promotionProductGroup = new HashMap<>();
        promotionProductVOS.forEach(product -> {
            spuIds.add(product.getSpuId());
            skuIds.add(product.getSkuId());
            // 按promotionId分组
            promotionProductGroup.computeIfAbsent(product.getPromotionId(), k -> new ArrayList<>()).add(product);
        });

        // 批量查询商品信息
        Map<Long, ProductSpu> spuMap = batchGetAndValidateSpus(new ArrayList<>(spuIds));
        Map<Long, ProductSku> skuMap = batchGetAndValidateSkus(new ArrayList<>(skuIds), spuMap);

        // 填充SKU图片
        promotionProductVOS.forEach(product ->
                product.setSkuImage(skuMap.getOrDefault(product.getSkuId(), new ProductSku()).getImage())
        );

        promotionVOS.forEach(promotionVO -> {
            promotionVO.setPromotionProductVO(promotionProductGroup.get(promotionVO.getId()));
        });

        // 按促销活动分组并找到最低价商品
        return promotionProductVOS.stream()
                .collect(Collectors.groupingBy(
                        PromotionProductVO::getPromotionId,
                        Collectors.collectingAndThen(
                                Collectors.toList(),
                                list -> list.stream()
                                        .min(Comparator.comparing(PromotionProductVO::getPromotionPrice))
                                        .orElse(null)
                        )
                ));
    }

    // 处理促销规则
    private Map<Long, List<PromotionRuleVO>> processPromotionRules(List<Long> promotionIds) {
        List<PromotionRuleVO> promotionRules = promotionRuleMapper.selectByPromotionIds(promotionIds);
        return CollUtil.isEmpty(promotionRules)
                ? Collections.emptyMap()
                : promotionRules.stream().collect(Collectors.groupingBy(PromotionRuleVO::getPromotionId));
    }

    // 填充商品信息
    private void fillProductInfo(List<PromotionVO> promotionVOS,
                                 Map<Long, PromotionProductVO> minPriceProductMap,
                                 Map<Long, List<PromotionRuleVO>> ruleGroupPromotion) {
        // 获取所有SPU ID用于查询主图
        Set<Long> spuIds = promotionVOS.stream()
                .map(PromotionVO::getSpuId).collect(Collectors.toSet());

        Map<Long, String> spuMainImagesMap = productSpuImagesMapper.selectMainImagesBySpuIds(new ArrayList<>(spuIds))
                .stream()
                .collect(Collectors.toMap(ProductSpuImages::getId, ProductSpuImages::getMainImages));

        // 批量查询SPU信息
        Map<Long, ProductSpu> spuMap = batchGetAndValidateSpus(new ArrayList<>(spuIds));

        promotionVOS.forEach(vo -> {
            // 设置商品名称和主图
            ProductSpu spu = spuMap.get(vo.getSpuId());
            if (spu != null) {
                vo.setProductName(spu.getSpuName());
                String mainImages = spuMainImagesMap.get(vo.getSpuId());
                vo.setProductMainImage(StringUtils.isBlank(mainImages) ? "" : mainImages.split(",")[0]);
            }

            // 设置价格信息（增加空检查）
            PromotionProductVO minPriceProduct = minPriceProductMap.get(vo.getId());
            if (minPriceProduct != null) {
                vo.setSkuPrice(minPriceProduct.getSkuPrice());
                vo.setPromotionPrice(minPriceProduct.getPromotionPrice());
            }

            // 设置促销规则（空集合代替null）
            vo.setPromotionRuleVOS(ruleGroupPromotion.getOrDefault(vo.getId(), Collections.emptyList()));
        });
    }

    /**
     * 批量获取并验证SPU
     */
    protected Map<Long, ProductSpu> batchGetAndValidateSpus(List<Long> spuIds) {
        List<ProductSpu> productSpus = productSpuMapper.selectSpuNameBySpuIds(spuIds);
        if (productSpus.size() != spuIds.size()) {
            throw new BusinessException(ErrorCode.PRODUCT_NOT_EXIST);
        }

        // 过滤已下架商品
        List<String> offlineSpus = productSpus.stream()
                .filter(spu -> spu.getStatus() != ProductStatus.AVAILABLE.getState())
                .map(ProductSpu::getSpuName)
                .toList();

        if (CollUtil.isNotEmpty(offlineSpus)) {
            throw new BusinessException(ErrorCode.PRODUCT_NOT_EXIST.getCode(),
                    JSON.stringify(offlineSpus) + ErrorCode.PRODUCT_NOT_EXIST.getMessage());
        }

        return productSpus.stream()
                .collect(Collectors.toMap(ProductSpu::getId, Function.identity()));
    }

    /**
     * 批量获取并验证SKU
     */
    protected Map<Long, ProductSku> batchGetAndValidateSkus(List<Long> skuIds, Map<Long, ProductSpu> spuMap) {
        List<ProductSku> skus = productSkuMapper.selectSkusByIds(skuIds);
        if (skus.size() != skuIds.size()) {
            throw new BusinessException(ErrorCode.SKU_NOT_EXIST);
        }

        // 验证SKU与SPU的关联关系
        skus.forEach(sku -> {
            if (!spuMap.containsKey(sku.getSpuId())) {
                throw new BusinessException(ErrorCode.SKU_SPU_MISMATCH);
            }
        });

        return skus.stream()
                .collect(Collectors.toMap(ProductSku::getId, Function.identity()));
    }


    @Override
    public PromotionVO queryPromotionDetail(Long id) {
        // 1. 分页查询促销活动基本信息
        PromotionVO promotionVO = promotionMapper.selectById(id);

        List<PromotionVO> promotionVOS = Collections.singletonList(promotionVO);
        List<Long> promotionIds = Collections.singletonList(id);

        // 3. 查询并处理促销商品信息
        Map<Long, PromotionProductVO> minPriceProductMap = processPromotionProducts(promotionVOS, promotionIds);

        // 4. 查询促销规则
        Map<Long, List<PromotionRuleVO>> ruleGroupPromotion = processPromotionRules(promotionIds);

        // 5. 查询商品信息并填充
        fillProductInfo(promotionVOS, minPriceProductMap, ruleGroupPromotion);

        return promotionVO;
    }

}
